package net.gdface.bean.jdk.descriptor;

import java.beans.IntrospectionException;
import java.lang.reflect.Method;
import com.google.common.base.Throwables;

import gu.sql2java.RowMetaData;
import gu.sql2java.UnnameRow;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * 实现对{@link gu.sql2java.UnnameRow}实例的属性封装
 * @author guyadong
 * @since 2.7.0
 */
public class UnnameRowPropertyDescriptor extends BaseNoStandardPropertyDescriptor {

	private final Method readMethod;
	private final Method writeMethod;
	private final Class<?> propertyType;
	private UnnameRowPropertyDescriptor(Class<?> propertyType, String name)
			throws IntrospectionException {
		super(checkNotNull(name,"field is null"), null, null);
		this.propertyType = checkNotNull(propertyType,"propertyType of %s is null",name);
		try {
			readMethod = getClass().getMethod("readMethod", Object.class,String.class);
			writeMethod = getClass().getMethod("writeMethod", Object.class,String.class,Object.class);
		} catch (Exception e) {
			Throwables.throwIfUnchecked(e);
			throw new RuntimeException(e);
		}
	}
	public UnnameRowPropertyDescriptor(RowMetaData rowMetaData, String name)
			throws IntrospectionException {
		this(checkNotNull(rowMetaData,"rowMetaData is null").columnTypeOf(name), name);
	}
	/**
	 * 字段读取方法实现
	 * @param bean 读取目标对象
	 * @param name 字段名
	 * @return 字段值
	 */
	public static Object readMethod(Object bean,String name){
		if(bean instanceof UnnameRow){
			return ((UnnameRow)bean).getValue(name);
		}
		return null;
	}
	/**
	 * 字段写入方法实现
	 * @param bean 写入目标对象
	 * @param name 字段名
	 * @param value 要写入的值
	 */
	public static void writeMethod(Object bean,String name,Object value){
		if(bean instanceof UnnameRow){
			((UnnameRow)bean).setValue(name, value);
		}
	}

	@Override
	public Method getReadMethod() {
		return readMethod;
	}

	@Override
	public Method getWriteMethod() {
		return writeMethod;
	}

	@Override
	public Class<?> getPropertyType() {
		return propertyType;
	}
	@Override
	public boolean isWritable(Object object){
		return null== object ? true : propertyType.isInstance(object);
	}
}
